﻿using project.B12.IRepository.Base;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;

namespace project.B12.Repository.Base
{
    public class SugarRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class, new()
    {
        protected readonly SqlSugarClient DB;
        public ISqlSugarClient Db => DB.GetConnectionWithAttr<TEntity>();

        public SugarRepository(IUnitOfWork unitOfWork)
        {
            DB = (SqlSugarClient)unitOfWork.GetDb();
           // var childDb =  DB.GetConnectionWithAttr<TEntity>();//线程安全用GetConnectionWithAttrScope
        }

        public Task<TEntity> QueryById(object objId)
        {
            //return  Task.Run(() => _db.Queryable<TEntity>().InSingle(objId));
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().In(objId).SingleAsync();
        }

        public Task<bool> AnyById(object objId)
        {
            //return  Task.Run(() => _db.Queryable<TEntity>().InSingle(objId));
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().In(objId).AnyAsync();
        }

        /// <summary>
        /// 功能描述:根据ID查询数据
        /// </summary>
        /// <param name="lstIds">id列表（必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]），如果是联合主键，请使用Where条件</param>
        /// <returns>数据实体列表</returns>
        public Task<List<TEntity>> QueryByIDs(object[] lstIds)
        {
            //return  Task.Run(() => _db.Queryable<TEntity>().In(lstIds).ToList());
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().In(lstIds).ToListAsync();
        }

        /// <summary>
        /// 写入实体数据
        /// </summary>
        /// <param name="entity">博文实体类</param>
        /// <returns></returns>
        public Task<int> Add(TEntity entity)
        {
            //var i = await Task.Run(() => _db.Insertable(entity).ExecuteReturnBigIdentity());
            ////返回的i是long类型,这里你可以根据你的业务需要进行处理
            //return (int)i;

            var insert = DB.AsTenant().GetConnectionWithAttr<TEntity>() .Insertable(entity);

            //这里你可以返回TEntity，这样的话就可以获取id值，无论主键是什么类型
            //var return3 = await insert.ExecuteReturnEntityAsync();

            return insert.ExecuteReturnIdentityAsync();
        }

        /// <summary>
        /// 批量插入实体(速度快)
        /// </summary>
        /// <param name="listEntity">实体集合</param>
        /// <returns>影响行数</returns>
        public Task<int> Add(List<TEntity> listEntity)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Insertable(listEntity).ExecuteCommandAsync();
        }

        /// <summary>
        /// 更新实体数据
        /// </summary>
        /// <param name="entity">博文实体类</param>
        /// <returns></returns>
        public Task<bool> Update(TEntity entity)
        {
            ////这种方式会以主键为条件
            //var i = await Task.Run(() => _db.Updateable(entity).ExecuteCommand());
            //return i > 0;
            //这种方式会以主键为条件
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Updateable(entity).ExecuteCommandHasChangeAsync();
        }

        public Task<bool> Update(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Updateable<TEntity>().SetColumns(columns).Where(whereExpression).ExecuteCommandHasChangeAsync();
        }

        public Task<int> Update(object operateAnonymousObjects)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Updateable<TEntity>(operateAnonymousObjects).ExecuteCommandAsync();
        }

        /// <summary>
        /// 根据实体删除一条数据
        /// </summary>
        /// <param name="entity">博文实体类</param>
        /// <returns></returns>
        public Task<bool> Delete(TEntity entity)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Deleteable(entity).ExecuteCommandHasChangeAsync();
        }

        /// <summary>
        /// 删除指定ID的数据
        /// </summary>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        public Task<bool> DeleteById(object id)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Deleteable<TEntity>().In(id).ExecuteCommandHasChangeAsync();
        }

        /// <summary>
        /// 删除指定ID集合的数据(批量删除)
        /// </summary>
        /// <param name="ids">主键ID集合</param>
        /// <returns></returns>
        public Task<bool> DeleteByIds(object[] ids)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Deleteable<TEntity>().In(ids).ExecuteCommandHasChangeAsync();
        }

        public Task<bool> Delete(Expression<Func<TEntity, bool>> whereExpression)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Deleteable<TEntity>().Where(whereExpression).ExecuteCommandHasChangeAsync();
        }

        public Task<bool> Delete(List<TEntity> deleteObjs)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Deleteable<TEntity>().Where(deleteObjs).ExecuteCommandHasChangeAsync();
        }

        /// <summary>
        /// 功能描述:查询所有数据
        /// </summary>
        /// <returns>数据列表</returns>
        public Task<List<TEntity>> Query()
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().ToListAsync();
        }

        /// <summary>
        /// 功能描述:查询数据列表
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns>数据列表</returns>
        public Task<List<TEntity>> Query(string where)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().WhereIF(!string.IsNullOrEmpty(where), where).ToListAsync();
        }

        /// <summary>
        /// 功能描述:查询数据列表
        /// </summary>
        /// <param name="whereExpression">whereExpression</param>
        /// <returns>数据列表</returns>
        public Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression)
        {
            //var dddbb = DB.AsTenant().GetConnectionWithAttr<TEntity>();
            //var list = dddbb.Queryable<TEntity>().WhereIF(whereExpression != null, whereExpression).ToListAsync();
            //return list;
            return DB.AsTenant().GetConnectionWithAttr<TEntity>() .Queryable<TEntity>().WhereIF(whereExpression != null, whereExpression).ToListAsync();
        }

        /// <summary>
        /// 功能描述:按照特定列查询数据列表带条件排序
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="whereExpression">过滤条件</param>
        /// <param name="expression">查询实体条件</param>
        /// <param name="orderByFields">排序条件</param>
        /// <returns></returns>
        public Task<List<TResult>> Query<TResult>(Expression<Func<TEntity, TResult>> expression, Expression<Func<TEntity, bool>> whereExpression, string orderByFields)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().OrderByIF(!string.IsNullOrEmpty(orderByFields), orderByFields).WhereIF(whereExpression != null, whereExpression).Select(expression).ToListAsync();
        }

        /// <summary>
        /// 功能描述:查询一个列表
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="orderByFields">排序字段，如name asc,age desc</param>
        /// <returns>数据列表</returns>
        public Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, string orderByFields)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().WhereIF(whereExpression != null, whereExpression).OrderByIF(orderByFields != null, orderByFields).ToListAsync();
        }

        /// <summary>
        /// 功能描述:查询一个列表
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="isAsc"></param>
        /// <returns></returns>
        public Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true)
        {
            //return  Task.Run(() => _db.Queryable<TEntity>().OrderByIF(orderByExpression != null, orderByExpression, isAsc ? OrderByType.Asc : OrderByType.Desc).WhereIF(whereExpression != null, whereExpression).ToList());
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().OrderByIF(orderByExpression != null, orderByExpression, isAsc ? OrderByType.Asc : OrderByType.Desc).WhereIF(whereExpression != null, whereExpression).ToListAsync();
        }

        /// <summary>
        /// 功能描述:查询前N条数据
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="top">前N条</param>
        /// <param name="orderByFields">排序字段，如name asc,age desc</param>
        /// <returns>数据列表</returns>
        public Task<List<TEntity>> Query(
            Expression<Func<TEntity, bool>> whereExpression,
            int top,
            string orderByFields)
        {
            return DB.AsTenant().GetConnectionWithAttr<TEntity>().Queryable<TEntity>().OrderByIF(!string.IsNullOrEmpty(orderByFields), orderByFields).WhereIF(whereExpression != null, whereExpression).Take(top).ToListAsync();
        }
    }
}
